using System;
using System.Collections.Generic;

namespace PropertyExpression.ReactiveRelation
{
    internal class DependencyManager<TCalcContext>
    {
        private readonly CalcStorage<TCalcContext> calcStorage;

        private readonly Dictionary<Type, LinkedList<IFormulaProxy<TCalcContext>>> dictionary =
            new Dictionary<Type, LinkedList<IFormulaProxy<TCalcContext>>>();

        public DependencyManager(CalcStorage<TCalcContext> calcStorage)
        {
            this.calcStorage = calcStorage;
        }

        public void Add(Type entityType, IFormulaProxy<TCalcContext> formulaProxy)
        {
            LinkedList<IFormulaProxy<TCalcContext>> formulaProxies;
            if (!dictionary.TryGetValue(entityType, out formulaProxies))
            {
                formulaProxies = new LinkedList<IFormulaProxy<TCalcContext>>();
                dictionary.Add(entityType, formulaProxies);
            }
            formulaProxies.AddLast(formulaProxy);
        }

        public void CalculateProperties(
            object entity, 
            CalculatedValueCache<TCalcContext> calculatedValueCache, 
            IPreviousValueProcessor previousValueProcessor)
        {
            LinkedList<IFormulaProxy<TCalcContext>> formulaProxies;
            if (dictionary.TryGetValue(entity.GetType(), out formulaProxies))
            {
                foreach (var formulaProxy in formulaProxies)
                {
                    if (formulaProxy.SetValueToEntity(entity, calculatedValueCache))
                    {
                        calcStorage.ReverseDependencyManager.SetIsCalculatedCells(
                            entity, formulaProxy.PropertyName, calculatedValueCache, previousValueProcessor,
                            delegate { return false; }
                            );
                    }
                }
            }
        }
    }
}